﻿using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace System
{
  public  class ReplaceWordText
    {
        /// <summary>
        /// 读取Word内容
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string ReadWordText(string fileName)
        {
            string WordTableCellSeparator = "true";// ConfigurationManager.AppSettings["WordTableCellSeparator"];
            string WordTableRowSeparator = "true";//ConfigurationManager.AppSettings["WordTableRowSeparator"];
            string WordTableSeparator = "true";//ConfigurationManager.AppSettings["WordTableSeparator"];
            //
            string CaptureWordHeader = "true";//ConfigurationManager.AppSettings["CaptureWordHeader"];
            string CaptureWordFooter = "true";//ConfigurationManager.AppSettings["CaptureWordFooter"];
            string CaptureWordTable = "true";//ConfigurationManager.AppSettings["CaptureWordTable"];
            string CaptureWordImage = "true";//ConfigurationManager.AppSettings["CaptureWordImage"];
            //
            string CaptureWordImageFileName = "true";// ConfigurationManager.AppSettings["CaptureWordImageFileName"];
            //
            string fileText = string.Empty;
            StringBuilder sbFileText = new StringBuilder();

            #region 打开文档
            XWPFDocument document = null;
            try
            {
                using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
                {
                    document = new XWPFDocument(file);
                }
            }
            catch (Exception)
            {
               // LogHandler.LogWrite(string.Format("文件{0}打开失败，错误：{1}", new string[] { fileName, e.ToString() }));
            }
            #endregion

            #region 页眉、页脚
            //页眉
            if (CaptureWordHeader == "true")
            {
                sbFileText.AppendLine("Capture Header Begin");
                foreach (XWPFHeader xwpfHeader in document.HeaderList)
                {
                    sbFileText.AppendLine(string.Format("{0}", new string[] { xwpfHeader.Text }));
                }
                sbFileText.AppendLine("Capture Header End");
            }
            //页脚
            if (CaptureWordFooter == "true")
            {
                sbFileText.AppendLine("Capture Footer Begin");
                foreach (XWPFFooter xwpfFooter in document.FooterList)
                {
                    sbFileText.AppendLine(string.Format("{0}", new string[] { xwpfFooter.Text }));
                }
                sbFileText.AppendLine("Capture Footer End");
            }
            #endregion

            #region 表格
            if (CaptureWordTable == "true")
            {
                sbFileText.AppendLine("Capture Table Begin");
                foreach (XWPFTable table in document.Tables)
                {
                    //循环表格行
                    foreach (XWPFTableRow row in table.Rows)
                    {
                        foreach (XWPFTableCell cell in row.GetTableCells())
                        {
                            sbFileText.Append(cell.GetText());
                            //
                            sbFileText.Append(WordTableCellSeparator);
                        }

                        sbFileText.Append(WordTableRowSeparator);
                    }
                    sbFileText.Append(WordTableSeparator);
                }
                sbFileText.AppendLine("Capture Table End");
            }
            #endregion

            #region 图片
            if (CaptureWordImage == "true")
            {
                sbFileText.AppendLine("Capture Image Begin");
                foreach (XWPFPictureData pictureData in document.AllPictures)
                {
                    string picExtName = pictureData.SuggestFileExtension();
                    string picFileName = pictureData.FileName;
                    byte[] picFileContent = pictureData.Data;
                    //
                    string picTempName = string.Format(CaptureWordImageFileName, new string[] { Guid.NewGuid().ToString() + "_" + picFileName + "." + picExtName });
                    //
                    using (FileStream fs = new FileStream(picTempName, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(picFileContent, 0, picFileContent.Length);
                        fs.Close();
                    }
                    //
                    sbFileText.AppendLine(picTempName);
                }
                sbFileText.AppendLine("Capture Image End");
            }
            #endregion

            //正文段落
            sbFileText.AppendLine("Capture Paragraph Begin");
            foreach (XWPFParagraph paragraph in document.Paragraphs)
            {
                sbFileText.AppendLine(paragraph.ParagraphText);

            }
            sbFileText.AppendLine("Capture Paragraph End");
            //

            //
            fileText = sbFileText.ToString();
            return fileText;
        }

        /// <summary>
        /// 替换word内容
        /// 变量替换正则表达式${Variable}
        /// <code>
        ///  WordTemplate template = new WordTemplate();
        ///  Dictionary<string,string> dic = new Dictionary<string,string>();
        ///  dic.Add("a0101", "123");
        ///  template.ReplaceTemplate("E:\\离职交接表.docx", "E:\\离职交接表1.docx",dic);
        /// </code>
        /// </summary>
        /// <param name="templateFileName">模版文件地址</param>
        /// <param name="wordFileName">新生成文件地址</param>
        /// <param name="keyValues">原字符替换后字符</param>
        public void ReplaceTemplate(string templateFileName,string wordFileName,IDictionary<string,string> keyValues) {
            using FileStream fileStream = File.OpenRead(templateFileName);
            //打开07（.docx）以上的版本的文档
            XWPFDocument docx = new XWPFDocument(fileStream);

            IList<XWPFParagraph> paragraphs = docx.Paragraphs;
            ReplaceParagraphList(paragraphs);
            IList<XWPFTable> tables = docx.Tables;
            ReplaceTableList(tables);
            using FileStream output = new FileStream(wordFileName,FileMode.Create);
            docx.Write(output);

            void ReplaceParagraphList(IList<XWPFParagraph> paragraphs) {
                //遍历段落
                foreach(var paragraph in paragraphs) {
                    ReplaceParagraph(paragraph);
                }
            }
            void ReplaceTableList(IList<XWPFTable> tables) {
                foreach(var table in tables) {
                    foreach(var row in table.Rows) {
                        foreach(var cell in row.GetTableCells()) {
                            ReplaceParagraphList(cell.Paragraphs);
                            ReplaceTableList(cell.Tables);
                        }
                    }
                }
            }

            void ReplaceParagraph(XWPFParagraph paragraph) {
                string text = paragraph.ParagraphText;
                Regex rgx = new Regex(@"\$\{\S+?\}");
                MatchCollection matchs = rgx.Matches(text);
                foreach(var mtch in matchs) {
                    string sc = mtch.ToString();
                    string key = sc.Substring(2).TrimEnd('}');
                    if(keyValues.TryGetValue(key,out string value)) {
                        paragraph.ReplaceText(sc,value);
                    }
                }
            }
        }

    }
}
